package com.example.demo.util;

import jakarta.xml.bind.DatatypeConverter;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;

/**
 * @description：Aes对称加密工具类.
 * @author：lw
 * @create_time：2024/2/27
 **/
public class AesUtil {

    public static String key = "3132333435363738393041424344454631323334353637383930414243444566";
    public static String iv = "939f8259ac92c5048053b9eb38046dd5";

    public static String encrypt(String plaintext){
         try{
             // 将密钥和初始化向量从十六进制字符串转为字节数组
             byte[] keyBytes = DatatypeConverter.parseHexBinary(key);
             byte[] ivBytes = DatatypeConverter.parseHexBinary(iv);

             // 创建SecretKeySpec对象
             SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

             // 创建IvParameterSpec对象
             IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

             // 初始化Cipher对象以进行加密
             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
             cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

             // 将明文转为字节数组
             byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8);

             // 执行加密操作
             byte[] encryptedBytes = cipher.doFinal(plaintextBytes);

             // 将加密后的字节数组转为Base64编码以便传输给前端
             return Base64.encodeBase64String(encryptedBytes);
         }catch (Exception e){
             throw  new RuntimeException(e.getMessage());
         }
    }


    public static String decrypt(String base64Ciphertext){
       try{
           // 将密钥和初始化向量从十六进制字符串转为字节数组
           byte[] keyBytes = DatatypeConverter.parseHexBinary(key);
           byte[] ivBytes = DatatypeConverter.parseHexBinary(iv);

           // 创建SecretKeySpec对象
           SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

           // 创建IvParameterSpec对象
           IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

           // 初始化Cipher对象以进行解密
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
           cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

           // 将Base64编码的密文转为字节数组
           byte[] ciphertextBytes = Base64.decodeBase64(base64Ciphertext);

           // 执行解密操作
           byte[] decryptedBytes = cipher.doFinal(ciphertextBytes);

           // 将解密后的字节数组转为UTF-8字符串
           return new String(decryptedBytes, StandardCharsets.UTF_8);
       }catch (Exception e){
           throw new RuntimeException(e.getMessage());
       }
    }

    // 生成key，先执行该方法生成key，前后端都使用生成的key
    public static String generateKey(){
       try{
           // 1. 获取AES算法的密钥生成器实例
           KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

           // 2. 设置AES密钥长度（只能是128、192或256位）
           int keySize = 128; // 根据实际需求选择密钥长度
           keyGenerator.init(keySize, new SecureRandom()); // 使用SecureRandom生成随机种子

           // 3. 生成AES密钥
           SecretKey secretKey = keyGenerator.generateKey();

           // 4. 打印密钥（以二进制编码形式显示）
           byte[] keyBytes = secretKey.getEncoded();
           System.out.println("生成的AES密钥（二进制）：" + Arrays.toString(keyBytes));

           // 若需要将密钥转为十六进制字符串以便存储或传输。生成的AES密钥（十六进制）
           return DatatypeConverter.printHexBinary(keyBytes);
       }catch (Exception e){
          e.printStackTrace();
       }
       return "";
    }

    // 生成iv，先执行该方法生成iv，前后端都使用生成的iv
    public static String generateRandomIv() {
        SecureRandom random = new SecureRandom();
        byte[] ivBytes = new byte[16];
        random.nextBytes(ivBytes);

        return Hex.encodeHexString(ivBytes);
    }
}
